#include "CreateHyperbolaWidget.h"

#include "Core/MainWindow.h"
#include <QMessageBox>
#include <vtkProperty.h>
#include <TopoDS.hxx>
#include <TopoDS_Edge.hxx>
#include "FeatureShape/FeatureShape.h"

CreateHyperbolaWidget::CreateHyperbolaWidget(MainWindow* inMainWindow, ShapeOperation* inOperation, QWidget* parent)
	: QRWCreateCurveWidget(inMainWindow, inOperation, parent)
	, ui(new Ui::CreateHyperbolaWidgetClass())
{
	ui->setupUi(this);

	ui->centerWidget->installEventFilter(this);
	ui->majorWidget->installEventFilter(this);
	ui->minorWidget->installEventFilter(this);

	ui->centerWidget->setStyleSheet("background-color:rgb(255,178,102)");

	m_centerPnt = new RWTripleFloatInput(ui->centerX, ui->centerY, ui->centerZ);
	m_majorVec = new RWTripleFloatInput(ui->majorX, ui->majorY, ui->majorZ);
	m_minorVec = new RWTripleFloatInput(ui->minorX, ui->minorY, ui->minorZ);

	m_mainWindow->SetSelectionMode(SM_Vertex);

	connect(ui->confirm, &QPushButton::clicked, this, &CreateHyperbolaWidget::onConfirm);
	connect(ui->cancel, &QPushButton::clicked, this, &CreateHyperbolaWidget::close);
	connect(ui->modify, &QPushButton::clicked, this, &CreateHyperbolaWidget::onApply);

	connect(ui->centerX, &QDoubleSpinBox::valueChanged, this, &CreateHyperbolaWidget::onPosChanged);
	connect(ui->centerY, &QDoubleSpinBox::valueChanged, this, &CreateHyperbolaWidget::onPosChanged);
	connect(ui->centerZ, &QDoubleSpinBox::valueChanged, this, &CreateHyperbolaWidget::onPosChanged);
	connect(ui->majorX, &QDoubleSpinBox::valueChanged, this, &CreateHyperbolaWidget::onPosChanged);
	connect(ui->majorY, &QDoubleSpinBox::valueChanged, this, &CreateHyperbolaWidget::onPosChanged);
	connect(ui->majorZ, &QDoubleSpinBox::valueChanged, this, &CreateHyperbolaWidget::onPosChanged);
	connect(ui->minorX, &QDoubleSpinBox::valueChanged, this, &CreateHyperbolaWidget::onPosChanged);
	connect(ui->minorY, &QDoubleSpinBox::valueChanged, this, &CreateHyperbolaWidget::onPosChanged);
	connect(ui->minorZ, &QDoubleSpinBox::valueChanged, this, &CreateHyperbolaWidget::onPosChanged);
	connect(ui->majorRadius, &QDoubleSpinBox::valueChanged, this, &CreateHyperbolaWidget::onPosChanged);
	connect(ui->minorRadius, &QDoubleSpinBox::valueChanged, this, &CreateHyperbolaWidget::onPosChanged);
	connect(ui->startLen, &QDoubleSpinBox::valueChanged, this, &CreateHyperbolaWidget::onPosChanged);
	connect(ui->endLen, &QDoubleSpinBox::valueChanged, this, &CreateHyperbolaWidget::onPosChanged);


	if (inOperation)
	{
		CreateShapeOperation* CreateOP = static_cast<CreateShapeOperation*>(inOperation);
		FeatureShapeHyperbola* HyperbolaShape = static_cast<FeatureShapeHyperbola*>(CreateOP->m_featureShape.get());
		ui->majorRadius->setValue(HyperbolaShape->_majorRadius);
		ui->minorRadius->setValue(HyperbolaShape->_minorRadius);
		ui->startLen->setValue(HyperbolaShape->_startLen);
        ui->endLen->setValue(HyperbolaShape->_endLen);
		m_centerPnt->SetValue(HyperbolaShape->_axis.Location());
		m_majorVec->SetValue(HyperbolaShape->_axis.XDirection());
		m_minorVec->SetValue(HyperbolaShape->_axis.YDirection());
	}

	cacheActor = m_mainWindow->createHyperbola(GetCurrentAxis().second, ui->majorRadius->value(), ui->minorRadius->value(), ui->startLen->value(), ui->endLen->value());
}

CreateHyperbolaWidget::~CreateHyperbolaWidget()
{
	delete ui;
	delete m_centerPnt;
	delete m_majorVec;
	delete m_minorVec;
}

void CreateHyperbolaWidget::onPosChanged()
{
	if (!cacheActor)
	{
		return;
	}

	// 批量修改
	if (bBatchChange)
	{
		return;
	}

	UpdateInner();
}

void CreateHyperbolaWidget::OnPickPosition(const gp_Pnt& inPosition)
{
	bBatchChange = true;
	if (focusIndex == 0)
	{
		m_centerPnt->SetValue(inPosition);
	}
	bBatchChange = false;

	UpdateInner();
}

ShapeOperation* CreateHyperbolaWidget::GetOperation()
{
	ShapeOperation* op = new CreateShapeOperation(tr("双曲线"), cacheActor->m_featureShape);
	return op;
}

void CreateHyperbolaWidget::GenerateFeatureShapeForCacheActor()
{
	cacheActor->m_featureShape.reset(new FeatureShapeHyperbola(cacheActor->OccShape(), 
		GetCurrentAxis().second, ui->majorRadius->value(), ui->minorRadius->value(), ui->startLen->value(), ui->endLen->value()));
}

bool CreateHyperbolaWidget::eventFilter(QObject* obj, QEvent* event)
{
	QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
	if (event->type() == QEvent::MouseButtonPress && mouseEvent->button() == Qt::LeftButton)
	{
		if (obj == ui->centerWidget && focusIndex != 0)
		{
			ui->centerWidget->setStyleSheet("background-color:rgb(255,178,102)");
			ui->majorWidget->setStyleSheet("background-color: #FFFFFF;");
			ui->minorWidget->setStyleSheet("background-color: #FFFFFF;");
			focusIndex = 0;
			m_mainWindow->SetSelectionMode(SM_Vertex);
		}
		if (obj == ui->majorWidget && focusIndex != 1)
		{
			ui->majorWidget->setStyleSheet("background-color:rgb(255,178,102)");
			ui->centerWidget->setStyleSheet("background-color: #FFFFFF;");
			ui->minorWidget->setStyleSheet("background-color: #FFFFFF;");
			focusIndex = 1;
			m_mainWindow->SetSelectionMode(SM_Edge);
		}
		if (obj == ui->minorWidget && focusIndex != 2)
		{
			ui->minorWidget->setStyleSheet("background-color:rgb(255,178,102)");
			ui->centerWidget->setStyleSheet("background-color: #FFFFFF;");
			ui->majorWidget->setStyleSheet("background-color: #FFFFFF;");
			focusIndex = 2;
			m_mainWindow->SetSelectionMode(SM_Edge);
		}
	}

	return QObject::eventFilter(obj, event);
}

void CreateHyperbolaWidget::OnPickDirection(const gp_Vec& inDirection)
{
	if (focusIndex == 0)
	{
		return;
	}

	bBatchChange = true;
	if (focusIndex == 1)
	{
		m_majorVec->SetValue(inDirection);
	}
	else if (focusIndex == 2)
	{
		m_minorVec->SetValue(inDirection);
	}
	bBatchChange = false;

	UpdateInner();
}

void CreateHyperbolaWidget::Reset()
{
	QRWCreateCurveWidget::Reset();

	m_centerPnt->SetValue(gp_Pnt());
	m_majorVec->SetValue(gp_Dir(0, 0, 1));
	m_minorVec->SetValue(gp_Dir(1, 0, 0));
	ui->majorRadius->setValue(2);
	ui->minorRadius->setValue(1);
	ui->startLen->setValue(1);
	ui->endLen->setValue(1);

	cacheActor = m_mainWindow->createHyperbola(GetCurrentAxis().second, ui->majorRadius->value(), ui->minorRadius->value(), ui->startLen->value(), ui->endLen->value());
	onPosChanged();
}

void CreateHyperbolaWidget::UpdateInner()
{
	if (ui->majorRadius->value() < ui->minorRadius->value())
	{
		QMessageBox::warning(this, tr("Error"), tr("长轴必须大于短轴!!!"));
	}

	std::pair<bool, gp_Ax2> axis = GetCurrentAxis();
	if (!axis.first)
	{
		return;
	}
	cacheActor = m_mainWindow->UpdateHyperbolaActor(cacheActor, axis.second, ui->majorRadius->value(), ui->minorRadius->value(), ui->startLen->value(), ui->endLen->value());
}

std::pair<bool, gp_Ax2> CreateHyperbolaWidget::GetCurrentAxis()
{
	std::pair<bool, gp_Ax2> res;
	gp_Dir xDir{ ui->majorX->value(), ui->majorY->value(), ui->majorZ->value() };
	gp_Dir yDir{ ui->minorX->value(), ui->minorY->value(), ui->minorZ->value() };

	if (!IsNearlyZero(xDir.Dot(yDir)))
	{
		QMessageBox::warning(this, tr("Error"), tr("长轴与短轴必须垂直!!!"));
		res.first = false;
		return res;
	}

	gp_Dir zDir = xDir.Crossed(yDir);
	res.first = true;
	res.second = gp_Ax2(gp_Pnt(ui->centerX->value(), ui->centerY->value(), ui->centerZ->value()), zDir, xDir);

	return res;
}
